package web

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"log"
	"mts/trans_srv/internal/domain"
	"mts/trans_srv/internal/service"
	middleware "mts/trans_srv/internal/web/middleware"
	"mts/trans_srv/internal/web/response"
	"net/http"
	"strconv"
	"time"
)

type ActionType string
type LogType string

const (
	ActionDeleteLan ActionType = "删除语言"
	ActionUpdateLan ActionType = "更新语言"
	ActionAddLan    ActionType = "创建语言"
	TypeCreate      LogType    = "create"
	TypeUpdate      LogType    = "update"
	TypeDelete      LogType    = "delete"
)

type LanguageHandler struct {
	service service.LanService
}

func NewLanguageHandler(service service.LanService) *LanguageHandler {
	return &LanguageHandler{service: service}
}
func (h *LanguageHandler) RegisterRoutes(group *gin.RouterGroup) {
	langGroup := group.Group("/languages")
	{
		langGroup.POST("/", middleware.JWTAuth(), middleware.IsAdminAuth(), h.Create)
		langGroup.GET("/:langID", middleware.JWTAuth(), h.GetByLangID)
		langGroup.PUT("/:langID", middleware.JWTAuth(), h.Update)
		langGroup.GET("/", h.List)
		langGroup.DELETE("/:langID", middleware.JWTAuth(), middleware.IsAdminAuth(), h.Delete)
		langGroup.PUT("/:langID/enable", middleware.JWTAuth(), middleware.IsAdminAuth(), h.UpdateEnabled) // 新增路由
		langGroup.GET("/enabled", h.GetEnableList)
		langGroup.GET("/count", h.Count)
	}

}

func (h *LanguageHandler) Create(c *gin.Context) {
	var lanInfo domain.CreateLanInfo
	if err := c.ShouldBindJSON(&lanInfo); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"message": "请求参数错误: " + err.Error()})
		return
	}
	language := domain.Language{
		LangID:  lanInfo.LangID,
		Name:    lanInfo.Name,
		Dsc:     lanInfo.Dsc,
		Enabled: lanInfo.Enabled,
	}
	if err := h.service.Create(c, language); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"message": "创建语言失败: " + err.Error()})
		return
	}
	//发送消息到rabbitmq服务
	h.SendMessage(c, ActionAddLan, TypeCreate, fmt.Sprintf("创建了(%s-%s)语言", language.Name, language.LangID))
	c.JSON(http.StatusCreated, language)
}

func (h *LanguageHandler) GetByLangID(c *gin.Context) {
	langID := c.Param("langID")
	language, err := h.service.GetByLangID(c, langID)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"message": "未找到语言"})
		return
	}
	c.JSON(http.StatusOK, language)
}
func (h *LanguageHandler) List(c *gin.Context) {
	// 获取分页参数
	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(c.DefaultQuery("pageSize", "10"))

	languages, err := h.service.List(c, page, pageSize)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"message": "获取语言列表失败"})
		return
	}

	languageResponses := make([]response.LanguageResponse, len(languages))
	for i, language := range languages {
		languageResponses[i] = *response.NewLanguageResponse(language)
	}

	c.JSON(http.StatusOK, &response.LanguageListResponse{
		LanguageResponse: languageResponses,
	})
}

func (h *LanguageHandler) Update(c *gin.Context) {
	langID := c.Param("langID")
	if langID == "" {
		c.JSON(http.StatusBadRequest, gin.H{"message": "语言ID不能为空"})
		return
	}
	// 检查语言是否存在
	existingLanguage, err := h.service.GetByLangID(c, langID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"message": "检查语言失败: " + err.Error()})
		return
	}
	if existingLanguage == nil {
		c.JSON(http.StatusNotFound, gin.H{"message": "语言不存在"})
		return
	}
	// 绑定请求数据到语言结构体
	var language domain.Language
	if err := c.ShouldBindJSON(&language); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"message": "请求参数错误: " + err.Error()})
		return
	}
	// 确保 LangID 和 ID 被正确设置
	language.LangID = langID
	// 打印 language 对象进行调试
	log.Printf("language to update: %+v", language)
	// 更新语言
	if err := h.service.Update(c, language); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"message": "更新语言失败: " + err.Error()})
		return
	}
	//发送消息到rabbitmq服务
	h.SendMessage(c, ActionUpdateLan, TypeUpdate, fmt.Sprintf("更新了%s(%s)", existingLanguage.Name, existingLanguage.LangID))
	c.JSON(http.StatusOK, gin.H{"message": "语言更新成功"})
}

func (h *LanguageHandler) UpdateEnabled(c *gin.Context) { // 新增方法
	langID := c.Param("langID")
	if langID == "" {
		c.JSON(http.StatusBadRequest, gin.H{"message": "语言ID不能为空"})
		return
	}

	// 检查语言是否存在
	existingLanguage, err := h.service.GetByLangID(c, langID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"message": "检查语言失败: " + err.Error()})
		return
	}
	if existingLanguage == nil {
		c.JSON(http.StatusNotFound, gin.H{"message": "语言不存在"})
		return
	}

	// 绑定请求数据到语言结构体
	var updateInfo struct {
		Enabled bool `json:"enabled"`
	}
	if err := c.ShouldBindJSON(&updateInfo); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"message": "请求参数错误: " + err.Error()})
		return
	}

	// 更新语言的启用状态
	existingLanguage.Enabled = updateInfo.Enabled
	if err := h.service.UpdateEnabled(c, existingLanguage); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"message": "更新语言启用状态失败"})
		return
	}

	var info string
	if !existingLanguage.Enabled {
		info = "启用"
	} else {
		info = "禁用"
	}
	//发送消息到rabbitmq
	h.SendMessage(c, ActionUpdateLan, TypeUpdate, fmt.Sprintf("%s了%s(%s)", info, existingLanguage.Name, existingLanguage.LangID))
	c.JSON(http.StatusOK, gin.H{"message": "语言启用状态更新成功"})
}

func (h *LanguageHandler) Delete(c *gin.Context) {
	langID := c.Param("langID")
	if langID == "" {
		c.JSON(http.StatusBadRequest, gin.H{"msg": "语言ID不能为空"})
		return
	}

	if err := h.service.Delete(c, langID); err != nil {
		log.Printf("删除语言失败: %v", err)
		c.JSON(http.StatusInternalServerError, gin.H{"msg": "删除语言失败: " + err.Error()})
		return
	}
	//发送消息到rabbitmq
	h.SendMessage(c, ActionDeleteLan, TypeDelete, fmt.Sprintf("删除了语言 %s", langID))
	c.JSON(http.StatusNoContent, gin.H{"msg": "删除语言成功"})
}

func (h *LanguageHandler) GetEnableList(c *gin.Context) {
	list, err := h.service.GetEnableList(c)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"message": "获取失败: " + err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"msg":  "获取成功",
		"data": list,
	})
}

func (h *LanguageHandler) getCurrentUser(ctx *gin.Context) *domain.CustomClaims {
	claims, _ := ctx.Get("claims")
	return claims.(*domain.CustomClaims)
}

func (h *LanguageHandler) SendMessage(ctx *gin.Context, a ActionType, t LogType, d string) {
	currentUser := h.getCurrentUser(ctx)
	//发送消息到rabbitmq服务
	err := h.service.Publish(map[string]interface{}{
		"user_id":   currentUser.NickName,
		"action":    a,
		"type":      t,
		"details":   d,
		"timestamp": time.Now(),
	})
	if err != nil {
		zap.S().Errorf("记录日志失败:%s", err)
	}
}

func (h *LanguageHandler) Count(ctx *gin.Context) {
	count, err := h.service.Count(ctx)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{
			"code": 400,
			"msg":  "系统异常",
		})
		return
	}
	ctx.JSON(http.StatusOK, gin.H{
		"lang": count,
	})
}
